from selenium.webdriver.remote.webdriver import WebDriver


def Page(cls):
    class WapperPage:
        def __init__(self, *args, **kargs):
            setattr(cls, "__getattr__", self.__inner)  # 给原类添加属性拦截器指向自己写的拦截器
            self.__locators_dict = {k[:-4]: v for k, v in list(cls.__dict__.items()) if
                                    k.endswith("_loc") and isinstance(v, tuple)}  # 将符合以_loc结尾的元组作为定位器加入内部字典
            self.page = cls(*args, **kargs)  # 原始类的实例
            self.driver = self.__get_webdriver()  # 获取到原始类中的WebDriver，未获取到会抛异常

        def __inner(self, attr):
            """
            自定义拦截器，将webelement_loc转换成webelement
            :param attr: 未匹配的请求的str类型
            :return: webelement or raise AttributeError
            """
            if attr in self.__locators_dict.keys():
                return self.__get_web_element(attr)
            else:
                raise AttributeError("{} object has no attribute '{}'".format(self.page.__class__, attr))

        def __getattr__(self, attr):
            """
            拦截请求转发给原类的属性拦截器
            :param attr: 未匹配的请求的str类型
            :return:
            """
            return getattr(self.page, attr)

        def __get_web_element(self, attr):
            webelement = self.driver.find_element(*self.__locators_dict[attr])
            return webelement

        def __get_webdriver(self):
            for k, v in self.page.__dict__.items():
                if isinstance(v, WebDriver):
                    return v
                else:
                    raise AttributeError("WebDriver should be set as Class attribute")

    return WapperPage
